<template>
  <el-dialog
    v-model="dialogValue"
    :title="title"
    width="600"
    append-to-body
    @open="openDialog"
    @close="handleClose"
  >
    <div v-loading="loading" element-loading-background="rgba(0,0,0,0.5)">
      <el-form ref="elFormRef" :model="form" label-width="auto">
        <!-- <el-form-item label="关联巷道" prop="name" :rules="{ required: true, message: '请选择关联巷道' }">
          <el-select v-model="item.deviceType">
            <el-option v-for="item in deviceTypeList" :key="item.id" :label="item.label" :value="item.id" />
          </el-select>
        </el-form-item> -->
        <el-form-item label="名称" prop="name" :rules="{ required: true, message: '请输入名称' }">
          <el-input v-model.trim="form.name" placeholder="请输入" />
        </el-form-item>
        <el-form-item label="坐标" prop="coordinates">
          <el-row :gutter="10" align="middle" class="coordinates-row">
            <el-col :span="8">
              <el-form-item prop="coordinates.x" :rules="rule">
                <el-input v-model.number="form.coordinates.x" placeholder="请输入">
                  <template #prepend>X:</template>
                </el-input>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item prop="coordinates.y" :rules="rule">
                <el-input v-model.number="form.coordinates.z" placeholder="请输入">
                  <template #prepend>Y:</template>
                </el-input>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item prop="coordinates.z" :rules="rule">
                <el-input v-model.number="form.coordinates.y" placeholder="请输入">
                  <template #prepend>H:</template>
                </el-input>
              </el-form-item>
            </el-col>
          </el-row>
        </el-form-item>
        <el-row v-for="(item, index) in form.detailDtos" :key="index" :gutter="10">
          <el-col :span="8">
            <el-form-item
              label="类型"
              :prop="`detailDtos.${index}.deviceType`"
              :rules="{ required: true, message: '请输入类型' }"
            >
              <el-select v-model="item.deviceType">
                <el-option
                  v-for="item in deviceTypeList"
                  :key="item.id"
                  :label="item.label"
                  :value="item.id"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="13">
            <el-form-item
              label="设备"
              :prop="`detailDtos.${index}.deviceIdList`"
              :rules="{ required: true, message: '请输入类型' }"
            >
              <el-select
                v-if="item.deviceType !== '002'"
                v-model="item.deviceIdList"
                multiple
                filterable
              >
                <template v-for="(eq, i) in deviceList[item.deviceType]" :key="i">
                  <el-option
                    :label="eq.cameraName || eq.areaLocation || eq.jzName"
                    :value="eq.cameraUuid || eq.cdCode || eq.jzNo"
                  />
                </template>
              </el-select>
              <el-cascader
                v-else
                v-model="item.deviceIdList"
                filterable
                :show-all-levels="false"
                :props="cascaderProps"
              />
            </el-form-item>
          </el-col>
          <el-col :span="3">
            <!-- 删除当前设备行的按钮 -->
            <el-button type="danger" plain :icon="Delete" @click="deleteEquipmentRow(index)" />
          </el-col>
        </el-row>
      </el-form>
      <!-- 添加设备行的工具按钮 -->
      <div class="coordinates-tools">
        <el-button type="primary" plain :icon="Plus" @click="addEquipmentRow"></el-button>
      </div>
    </div>

    <!-- 对话框底部按钮区域 -->
    <template #footer>
      <div class="dialog-footer">
        <el-button :disabled="loading" @click="dialogValue = false">取消</el-button>
        <el-button :loading="loading" plain type="primary" @click="submit"> 确定 </el-button>
      </div>
    </template>
  </el-dialog>
</template>
<script setup lang="ts">
import { computed, Ref, ref, onMounted, type PropType } from 'vue'
import { type FormInstance } from 'element-plus'
import { Object3D, Vector3 } from 'three'
import {
  getCameraList,
  getDeviceTypeDict,
  getSensorList,
  getrRyjzList,
  saveDeviceAnnotation,
  getSensorTypeDict,
  getDeviceAnnotationDetail
} from '@renderer/api'
import { storeToRefs } from 'pinia'
import { useActiveObject } from '@renderer/stores/activeObject'
import { Equipment, useAddTools } from '@renderer/utils/useAddTools'
import { Plus, Delete } from '@element-plus/icons-vue'
import { cloneDeep } from 'lodash'
import { ContentMenuInfo } from '@renderer/components/b-contextmenu.vue'

// 定义对话框的标题
const title = ref('添加设备')

// 定义组件的 props
const props = defineProps({
  modelValue: {
    type: Boolean
  },
  check: {
    type: Boolean,
    default: false
  },
  type: {
    type: String as PropType<'add' | 'edit'>,
    default: 'add'
  },
  info: {
    type: Object as PropType<ContentMenuInfo>
  }
})

// 定义组件的事件发射器
const emit = defineEmits({
  'update:modelValue': (val: boolean) => val
})

// 表单加载状态
const loading = ref(false)
// 存储设备类型列表
const deviceTypeList = ref<{ label: string; id: string }[]>([])
const deviceList = ref({})
/**
 * 获取设备类型列表
 */
async function getDeviceTypes() {
  const { data } = await getDeviceTypeDict()
  deviceTypeList.value = data
}
// 调用函数获取设备类型列表
getDeviceTypes()
getDeviceList()
// 使用激活对象的状态管理 store
const activeObjectStore = useActiveObject()
const { activeShallowRef }: { activeShallowRef: Ref<Object3D> } = storeToRefs(activeObjectStore)

/**
 * 对话框打开时的回调函数
 */
async function openDialog() {
  if (props.info) {
    form.value.coordinates = props.info.position
    form.value.name = props.info.name
  }
  if (props.type === 'edit') {
    const obj = JSON.parse(JSON.stringify(activeShallowRef.value))
    title.value = '修改 - ' + obj.object.name
    // obj.object.userData.id
    loading.value = true
    const { data } = await getDeviceAnnotationDetail({
      id: obj.object.userData.id || obj.object.uuid
    })
    form.value = {
      ...data,
      coordinates: activeShallowRef.value.position.clone(),
      detailDtos: data.detailDtos.map((item: any) => ({
        deviceType: item.deviceType,
        detailVos: item.detailVos,
        deviceIdList:
          item.deviceType === '002'
            ? item.deviceIdList.map((id: string) => id.split(','))
            : item.deviceIdList
      }))
    }
    loading.value = false
  }
}

// 计算属性，用于双向绑定对话框的显示状态
const dialogValue = computed({
  get() {
    return props.modelValue
  },
  set(val) {
    emit('update:modelValue', val)
  }
})

// 坐标输入框的验证规则
const rule = [{ required: true, message: '请输入坐标' }]

// 存储表单数据
const form = ref<Equipment>({
  id: '',
  name: '',
  detailDtos: [],
  coordinates: new Vector3()
})

/**
 * 处理设备类型变更的回调函数
 * @param val - 选中的设备类型 ID
 * @param item - 当前设备项
 */
async function getDeviceList() {
  const [cameras, sensors, jzs] = await Promise.all([
    getCameraList(),
    getSensorList(),
    getrRyjzList()
  ])
  deviceList.value = {
    '001': jzs.data,
    '002': sensors.data,
    '003': cameras.data
  }
}

const sensorTypeList = ref<{ label: string; id: string }[]>([])
onMounted(async () => {
  const { data } = await getSensorTypeDict()
  sensorTypeList.value = data
})
const cascaderProps: cascaderProps = {
  lazy: true,
  multiple: true,
  expandTrigger: 'hover',
  lazyLoad: async (node, resolve) => {
    const { level } = node
    if (level === 0) {
      resolve(
        sensorTypeList.value.map((item: any) => ({
          label: item.label,
          value: item.id,
          leaf: false
        }))
      )
    } else if (level === 1) {
      const arr = []
      deviceList.value['002']?.forEach((item: any) => {
        if (item.sensorType === node.value) {
          arr.push({
            label: item.areaLocation,
            value: item.cdCode,
            leaf: true
          })
        }
      })
      resolve(arr)
    }
  }
}
/**
 * 添加一个新的设备行
 */
function addEquipmentRow() {
  form.value.detailDtos.push({
    deviceType: '',
    deviceIdList: []
  })
}

/**
 * 删除指定索引的设备行
 * @param index - 要删除的设备行的索引
 */
function deleteEquipmentRow(index: number) {
  form.value.detailDtos.splice(index, 1)
}

// 表单引用
const elFormRef = ref<FormInstance>()

// 导入编辑设备的工具函数
const { editEquipment } = useAddTools()

/**
 * 提交表单的回调函数
 */
function submit() {
  elFormRef.value?.validate(async (valid) => {
    if (valid) {
      try {
        loading.value = true
        const { data } = await saveDeviceAnnotation({
          ...form.value.coordinates,
          h: form.value.coordinates.y,
          name: form.value.name,
          id: form.value.id,
          detailDtos: form.value.detailDtos.map((item) => ({
            deviceType: item.deviceType,
            deviceIdList:
              item.deviceType === '002'
                ? item.deviceIdList.map((id: string) => id.join(','))
                : item.deviceIdList
          }))
        })
        if (!form.value.id) {
          form.value.id = data.id
        }
        editEquipment(cloneDeep(form.value))
        dialogValue.value = false
      } finally {
        loading.value = false
      }
    }
  })
}

/**
 * 对话框关闭时的回调函数
 */
function handleClose() {
  elFormRef.value?.resetFields()
  form.value = {
    id: '',
    name: '',
    detailDtos: [],
    coordinates: new Vector3()
  }
}
</script>
<style lang="scss" scoped>
.coordinates-row {
  user-select: none;
  margin-bottom: 10px;

  ::v-deep(.el-input-group__prepend) {
    padding: 0 10px;
  }

  &.dragTop {
    border-top: 1px dashed var(--active-color);
  }

  &.dragBottom {
    border-bottom: 1px dashed var(--active-color);
  }
}

.coordinates-tools {
  text-align: center;

  & > .el-button {
    width: 80px;
  }
}

:deep(.el-cascader) {
  width: 100%;
}
</style>
